package main

import (
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

func main() {
	/* websocket */
	hub := newHub()
	go hub.run()
	http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
		serveWs(hub, w, r)
	})

	/* static resource */
	http.Handle("/css/", http.FileServer(http.Dir("static")))
	http.Handle("/js/", http.FileServer(http.Dir("static")))

	http.HandleFunc("/", chatPage)
	http.HandleFunc("/index", index)
	http.HandleFunc("/404", notFound)
	http.HandleFunc("/do", handleDo)
	http.HandleFunc("/upload", handleUpload)

	log.Println("Start server...")
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe : ", err)
	}
}

// 将上传的文件放本目录
func handleUpload(w http.ResponseWriter, r *http.Request) {
	file, fileInfo, err := r.FormFile("file")
	if err != nil {
		log.Fatal(err)
	}
	f, err := os.Create(fileInfo.Filename)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	_, err = io.Copy(f, file)
	if err != nil {
		log.Fatal(err)
	}
	w.Write([]byte(fileInfo.Filename + " OK"))
}

// 打印请求的body并返回ok
func handleDo(w http.ResponseWriter, r *http.Request) {
	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		tmpl, _ := template.ParseFiles("static/html/50x.html")
		tmpl.Execute(w, map[string]string{
			"title": err.Error(),
		})
		return
	}
	text := string(data)
	log.Println(text)
	w.Write([]byte("OK"))
}

// 返回chat页面
func chatPage(w http.ResponseWriter, r *http.Request) {
	f, err := http.Dir("static/html").Open("chat.vue")
	if err != nil {
		log.Fatal(err)
		return
	}
	data, err := ioutil.ReadAll(f)
	if err != nil {
		log.Fatal(err)
		return
	}
	w.Write(data)
}

// 主页(静态页)
func index(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("static/html/index.html")
	if err != nil {
		log.Fatal("template.ParseFiles : ", err)
		return
	}
	t.Execute(w, nil)
}

// 404(静态页)
func notFound(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("static/html/404.html")
	if err != nil {
		log.Fatal("template.ParseFiles : ", err)
		return
	}
	t.Execute(w, nil)
}

// 每个ws连接都会分配一个client
func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	client := &Client{hub: hub, conn: conn, send: make(chan []byte, 256)}
	hub.Register(client)

	go client.WritePump()
	go client.ReadPump()
}
